<template>
  <div class="graph-analysis-view">
    <tabs
      ref="tab"
      v-model="activeTabId"
      :min-hidden-width="120"
      :tabs="tabs"
      :project-id="projectId"
    />
    <div
      id="graph-analysis-content"
      ref="analysisSection"
      class="graph-analysis-content"
    >
      <div
        id="analysis-left-graph"
        class="analysis-left-graph"
        :style="{ width: `calc(100% - ${drawerWidth}px)` }"
      >
        <graph-analysis-section
          ref="graphAnalysisSection"
          :project-id="projectId"
        />
      </div>
      <div
        id="analysis-right-drawer"
        class="analysis-right-drawer"
        :project-id="projectId"
        :style="{ width: drawerWidth + 'px' }"
      >
        <div id="drawer-resize" class="drag-two-resize"></div>
        <right-drawer
          @style-layout-run="styleLayoutRun"
          @data-filter-run="dataFilterRun"
        />
        <div class="handler" @click="toggleSettingPanel">
          <a-icon :type="settingIsOpen ? 'right' : 'left'" />
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
import Tabs from '@/components/graph-analysis/Tabs.vue'
import GraphAnalysisSection from '@/components/graph-analysis/GraphAnalysisSection.vue'
import GraphAnalysis from '@/store/modules/graphanalysis'
import RightDrawer from '@/components/graph-analysis/RightDrawer.vue'
import { setLocalStorage, getLocalStorage } from '@/util/util'

@Component({
  components: {
    Tabs,
    GraphAnalysisSection,
    RightDrawer,
  },
  directives: {
    focus: {
      inserted: (element: any) => {
        element.focus()
      },
    },
  },
})
export default class GraphAnalysisView extends Vue {
  public projectId: number = 0 // 当前 项目 Id

  private drawerWidth: number = 406
  private drawerMinWidth: number = 406 // 右侧最小宽度
  private drawerMaxWidth: number = 406 // 最大宽度， 初始化会重新赋值
  private leftBox: any = null // 左侧 dom
  private rightBox: any = null // 右侧 dom
  private resizeBar: any = null // 拖拽 bar
  private resizeContent: any = null // 整体的 dom
  public settingIsOpen: boolean = true // 抽屉状态

  public created() {
    this.projectId = Number(this.$route.params.id)
    GraphAnalysis.graphSetProjectId(this.projectId)
    this.queryGraphArrayByProjectId()
  }
  // 获取当前 项目 Id 初始化
  public mounted() {
    this.initViewEvent()
  }

  /**
   * 请求所有的graph tabs， 默认进入，激活第一个tab id，
   */
  public async queryGraphArrayByProjectId() {
    const result: any = await GraphAnalysis.queryGraphTabs(this.projectId)
    // 进入页面
    // 1. loadToGraphAnalysisId 图构建跳转来的 graphId 存在，activeTabId = loadToGraphAnalysisId
    // 2. 若：跳转 graphId 存在， 检查 localStorage graphAnalysisId 是否再当前 graphId Array 中,
    // 3. 若：不在， 默认取第一个 graphId
    if (GraphAnalysis.loadToGraphAnalysisId) {
      GraphAnalysis.setActiveTabId(GraphAnalysis.loadToGraphAnalysisId)
      GraphAnalysis.setLoadToGraphAnalysisId(null) // 用后置空
      return
    }
    const { tabsData } = result
    if (tabsData.length > 0) {
      const tabsIdArray: number[] =
        tabsData.length > 0 ? tabsData.map((tab: any) => tab.id) : []
      const graphId: number = Number(getLocalStorage('graphAnalysisId')) // window.localStorage 存储的 graphId, 刷新定位 tab
      if (graphId && tabsIdArray.includes(graphId)) {
        GraphAnalysis.setActiveTabId(graphId)
        return
      }
      GraphAnalysis.setActiveTabId(result.tabsData[0].id)
    } else {
      this.$message.warning('请先创建图！')
    }
  }

  /**
   * 初始化绑定事件 等
   */
  public initViewEvent() {
    this.leftBox = document.querySelector('#analysis-left-graph') as any
    this.rightBox = document.querySelector('#analysis-right-drawer') as any
    this.resizeBar = document.querySelector('#drawer-resize') as HTMLElement
    this.resizeContent = this.$refs.analysisSection as HTMLElement
    this.drawerMaxWidth = this.resizeContent.getBoundingClientRect().width
    this.dragTwoColDiv()
    window.addEventListener('resize', this.handleResize)
    // document.addEventListener('mouseup', this.globalKeyUp)
  }

  public beforeDestroy() {
    window.removeEventListener('resize', this.handleResize)
    // document.removeEventListener('mouseup', this.globalKeyUp)
  }

  // 页面退出销毁 当前激活的 tabId 即 graphId
  public destroyed() {
    GraphAnalysis.setActiveTabId(null)
  }

  /**
   * window resize
   */
  private handleResize() {
    this.drawerMaxWidth = this.resizeContent.getBoundingClientRect().width
    this.leftBox.style.width = `${this.drawerMaxWidth - this.drawerWidth}px`
  }

  // 两列拖动改变两列宽度
  private dragTwoColDiv() {
    const mouseDownEvent: any = ($event: any) => {
      const initLeftWidth: any = this.leftBox.getBoundingClientRect().width
      const initRightWidth: any = this.rightBox.getBoundingClientRect().width
      const startX = $event.clientX
      const mouseMoveEvent: any = (event: any) => {
        if (!this.settingIsOpen) {
          return
        }
        const endX = event.clientX
        const moveLength = endX - startX
        let rightWidth: any = initRightWidth - moveLength
        let leftWidth: any = initLeftWidth + moveLength
        if (rightWidth < this.drawerMinWidth) {
          rightWidth = this.drawerMinWidth
          leftWidth = this.drawerMaxWidth - this.drawerMinWidth
        }
        if (rightWidth > this.drawerMaxWidth) {
          rightWidth = this.drawerMaxWidth
          leftWidth = 0
        }
        this.leftBox.style.width = `${leftWidth}px`
        this.rightBox.style.width = `${rightWidth}px`
        this.drawerWidth = rightWidth
      }
      document.addEventListener('mousemove', mouseMoveEvent)
      const mouseUpEvent: any = () => {
        document.removeEventListener('mousemove', mouseMoveEvent)
        document.removeEventListener('mouseup', mouseUpEvent)
        // eslint-disable-next-line @typescript-eslint/no-unused-expressions
        this.resizeBar.releaseCapture && this.resizeBar.releaseCapture()
      }
      document.addEventListener('mouseup', mouseUpEvent)
      // eslint-disable-next-line @typescript-eslint/no-unused-expressions
      this.resizeBar.setCapture && this.resizeBar.setCapture()
      return false
    }
    this.resizeBar.addEventListener('mousedown', mouseDownEvent)

    this.$once('hook:beforeDestroy', () => {
      this.resizeBar.removeEventListener('mousedown', mouseDownEvent)
    })
  }

  // 获取当前 tab 数据
  public get tabs() {
    return GraphAnalysis.tabsData
  }

  // 获取当前 选中的tab Id
  public get activeTabId() {
    return GraphAnalysis.activeTabId
  }

  @Watch('activeTabId')
  public watchData(graphId: number) {
    setLocalStorage('graphAnalysisId', String(graphId))
  }

  /**
   * toggle 右侧抽屉
   */
  public toggleSettingPanel() {
    this.settingIsOpen = !this.settingIsOpen
    this.$nextTick(() => {
      if (!this.settingIsOpen) {
        this.drawerWidth = 0
        return
      }
      this.drawerWidth = 400
    })
  }

  /**
   * 样式 / 布局 run event $event
   */
  public styleLayoutRun(runInfo: any) {
    const graphAnalysisSection: any = this.$refs.graphAnalysisSection as Vue
    graphAnalysisSection.graphRun(runInfo)
  }

  // 执行过滤器
  public dataFilterRun() {
    const graphAnalysisSection: any = this.$refs.graphAnalysisSection as Vue
    graphAnalysisSection.queryGraphById('过滤结果为空')
  }
}
</script>

<style lang="less" scoped>
@import '@/constants';

.graph-analysis-view {
  height: calc(100vh - @HEADER_HEIGHT);
  position: relative;
  width: calc(100% - 160px);

  .graph-analysis-content {
    display: flex;
    // tab height
    height: calc(100% - 38px);
    justify-content: space-between;
    width: 100%;

    .analysis-left-graph {
      background: #fff;
      border-right: 1px solid #e9e9e9;
      height: 100%;
      min-width: 640px;
    }

    .analysis-right-drawer {
      height: 100%;
      position: relative;

      .drag-two-resize {
        background-color: transparent;
        cursor: col-resize;
        height: 100%;
        left: -6px;
        position: absolute;
        width: 5px;
        z-index: 100;
      }

      .handler {
        background: #dee3f7;
        color: #1e49f8;
        cursor: pointer;
        font-size: 9px;
        height: 70px;
        left: -12px;
        line-height: 70px;
        position: absolute;
        text-align: center;
        top: 50%;
        transform: translateY(-100%);
        width: 12px;
        z-index: 101;

        &::before,
        &::after {
          border: 6px solid #dee3f7;
          content: '';
          height: 0;
          left: 0;
          position: absolute;
          width: 0;
        }

        &::before {
          border-left-color: transparent;
          border-top-color: transparent;
          top: -12px;
        }

        &::after {
          border-bottom-color: transparent;
          border-left-color: transparent;
          bottom: -12px;
        }
      }
    }
  }
}
</style>
